home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / cdrtools-1.10 / libhfs_iso / block.c next >
Encoding:
C/C++ Source or Header  |  2000-03-05  |  5.2 KB  |  223 lines

  1. /*
  2.  * hfsutils - tools for reading and writing Macintosh HFS volumes
  3.  * Copyright (C) 1996, 1997 Robert Leslie
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or
  8.  * (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19.  
  20. #include <mconfig.h>
  21. #include <strdefs.h>
  22. #include <sys/types.h>
  23. #include <unixstd.h>
  24. #include <errno.h>
  25. #include <time.h>
  26.  
  27. #include "internal.h"
  28. #include "data.h"
  29. #include "block.h"
  30. #include "low.h"
  31.  
  32. #ifdef DEBUG
  33. #include <stdio.h>
  34. #endif /* DEBUG */
  35.  
  36. /*
  37.  * NAME:    block->readlb()
  38.  * DESCRIPTION:    read a logical block from a volume
  39.  */
  40. int b_readlb(vol, num, bp)
  41.     hfsvol        *vol;
  42.     unsigned long    num;
  43.     block        *bp;
  44. {
  45. #ifndef APPLE_HYB
  46.   int bytes;
  47. #endif
  48. #ifdef APPLE_HYB
  49.   block *b;
  50.   hce_mem *hce;
  51.  
  52. #ifdef DEBUG
  53.   fprintf(stderr,"b_readlb: start block = %d\n", vol->vstart + num);
  54. #endif /* DEBUG */
  55.  
  56.   hce = vol->hce;
  57.  
  58. /* Check to see if requested block is in the HFS header or catalog/exents
  59.    files. If it is, read info from memory copy. If not, then something
  60.    has gone horribly wrong ... */
  61.  
  62.   if (num < hce->hfs_hdr_size) 
  63.       b = (block *)hce->hfs_hdr + num;
  64.   else if (num < hce->hfs_hdr_size + hce->hfs_ce_size)
  65.       b = (block *)hce->hfs_ce + num - hce->hfs_hdr_size;
  66.   else
  67.     {
  68.       ERROR(EIO, "should not happen!");
  69.       return -1;
  70.     }
  71.  
  72.   memcpy(bp, b, HFS_BLOCKSZ);
  73.  
  74. #else
  75.  
  76.   if (lseek(vol->fd, (vol->vstart + num) * HFS_BLOCKSZ, SEEK_SET) < 0)
  77.     {
  78.       ERROR(errno, "error seeking device");
  79.       return -1;
  80.     }
  81.  
  82.   bytes = read(vol->fd, bp, HFS_BLOCKSZ);
  83.   if (bytes < 0)
  84.     {
  85.       ERROR(errno, "error reading from device");
  86.       return -1;
  87.     }
  88.   else if (bytes == 0)
  89.     {
  90.       ERROR(EIO, "read EOF on volume");
  91.       return -1;
  92.     }
  93.   else if (bytes != HFS_BLOCKSZ)
  94.     {
  95.       ERROR(EIO, "read incomplete block");
  96.       return -1;
  97.     }
  98. #endif /* APPLE_HYB */
  99.   return 0;
  100. }
  101.  
  102. /*
  103.  * NAME:    block->writelb()
  104.  * DESCRIPTION:    write a logical block to a volume
  105.  */
  106. int b_writelb(vol, num, bp)
  107.     hfsvol        *vol;
  108.     unsigned long    num;
  109.     block        *bp;
  110. {
  111. #ifndef APPLE_HYB
  112.   int bytes;
  113. #endif
  114. #ifdef APPLE_HYB
  115.   block *b;
  116.   hce_mem *hce;
  117.  
  118. #ifdef DEBUG
  119.   fprintf(stderr,"b_writelb: start block = %d\n", vol->vstart + num);
  120. #endif /* DEBUG */
  121.  
  122.    hce = vol->hce;
  123.  
  124. /* Check to see if requested block is in the HFS header or catalog/exents
  125.    files. If it is, write info to memory copy. If not, then it's a block
  126.    for an ordinary file - and as we are writing the files later, then just
  127.    ignore and return OK */
  128.   if (num < hce->hfs_hdr_size) 
  129.       b = (block *)hce->hfs_hdr + num;
  130.   else if (num < hce->hfs_hdr_size + hce->hfs_ce_size)
  131.       b = (block *)hce->hfs_ce + num - hce->hfs_hdr_size;
  132.   else
  133.     {
  134. #ifdef DEBUG
  135.       fprintf(stderr,"b_writelb: ignoring\n");
  136. #endif /* DEBUG */
  137.       return 0;
  138.     }
  139.  
  140.   memcpy(b, bp, HFS_BLOCKSZ);
  141.  
  142. #else
  143.  
  144.   if (lseek(vol->fd, (vol->vstart + num) * HFS_BLOCKSZ, SEEK_SET) < 0)
  145.     {
  146.       ERROR(errno, "error seeking device");
  147.       return -1;
  148.     }
  149.  
  150.   bytes = write(vol->fd, bp, HFS_BLOCKSZ);
  151.  
  152.   if (bytes < 0)
  153.     {
  154.       ERROR(errno, "error writing to device");
  155.       return -1;
  156.     }
  157.   else if (bytes != HFS_BLOCKSZ)
  158.     {
  159.       ERROR(EIO, "wrote incomplete block");
  160.       return -1;
  161.     }
  162. #endif /* APPLE_HYB */
  163.   return 0;
  164. }
  165.  
  166. /*
  167.  * NAME:    block->readab()
  168.  * DESCRIPTION:    read a block from an allocation block from a volume
  169.  */
  170. int b_readab(vol, anum, idx, bp)
  171.     hfsvol        *vol;
  172.     unsigned int    anum;
  173.     unsigned int    idx;
  174.     block        *bp;
  175. {
  176.   /* verify the allocation block exists and is marked as in-use */
  177.  
  178.   if (anum >= vol->mdb.drNmAlBlks)
  179.     {
  180.       ERROR(EIO, "read nonexistent block");
  181.       return -1;
  182.     }
  183.   else if (vol->vbm && ! BMTST(vol->vbm, anum))
  184.     {
  185.       ERROR(EIO, "read unallocated block");
  186.       return -1;
  187.     }
  188.  
  189.   return b_readlb(vol, vol->mdb.drAlBlSt + anum * vol->lpa + idx, bp);
  190. }
  191.  
  192. /*
  193.  * NAME:    b->writeab()
  194.  * DESCRIPTION:    write a block to an allocation block to a volume
  195.  */
  196. int b_writeab(vol, anum, idx, bp)
  197.     hfsvol        *vol;
  198.     unsigned int    anum;
  199.     unsigned int    idx;
  200.     block        *bp;
  201. {
  202.   /* verify the allocation block exists and is marked as in-use */
  203.  
  204.   if (anum >= vol->mdb.drNmAlBlks)
  205.     {
  206.       ERROR(EIO, "write nonexistent block");
  207.       return -1;
  208.     }
  209.   else if (vol->vbm && ! BMTST(vol->vbm, anum))
  210.     {
  211.       ERROR(EIO, "write unallocated block");
  212.       return -1;
  213.     }
  214.  
  215.   vol->mdb.drAtrb &= ~HFS_ATRB_UMOUNTED;
  216.   vol->mdb.drLsMod = d_tomtime(time(0));
  217.   ++vol->mdb.drWrCnt;
  218.  
  219.   vol->flags |= HFS_UPDATE_MDB;
  220.  
  221.   return b_writelb(vol, vol->mdb.drAlBlSt + anum * vol->lpa + idx, bp);
  222. }
  223.